import re
import logging

logger = logging.getLogger(__name__)

def convert_quartz_to_apscheduler(quartz_cron: str) -> str:
    """
    将Quartz风格的cron表达式转换为APScheduler兼容的格式
    
    Args:
        quartz_cron: Quartz风格的cron表达式
        
    Returns:
        APScheduler兼容的cron表达式
    """
    # 如果已经是APScheduler格式，直接返回
    if len(quartz_cron.split()) <= 6 and '?' not in quartz_cron:
        return quartz_cron
        
    logger.debug(f"转换Quartz cron表达式: {quartz_cron}")
    
    # 处理空格和制表符
    quartz_cron = re.sub(r'\s+', ' ', quartz_cron.strip())
    
    # 拆分cron表达式
    parts = quartz_cron.split()
    
    # Quartz cron表达式格式: 秒 分 时 日 月 周 [年]
    if len(parts) < 6:
        raise ValueError(f"无效的Quartz cron表达式: {quartz_cron}, 至少需要6个字段")
    
    second, minute, hour, day_of_month, month, day_of_week = parts[:6]
    
    # 转换特殊字符
    # 1. 处理 '?' - 在Quartz中, '?' 等同于 '*'
    if day_of_month == '?':
        day_of_month = '*'
    if day_of_week == '?':
        day_of_week = '*'
    
    # 2. 处理 '/' - 增量值
    # APScheduler也支持 '/', 但是需要确保格式一致
    
    # 3. 处理 'L' - 在月中的最后一天或在月中的最后一个特定的某天
    # 日期字段的 'L' 表示月中的最后一天
    if day_of_month == 'L':
        day_of_month = 'last'
    # 星期字段的 'L' 表示每月的最后一个星期几, 例如 '5L' 表示最后一个星期五
    day_of_week = re.sub(r'(\d+)L', r'last\1', day_of_week)
    
    # 4. 处理 'W' - 工作日
    # APScheduler不直接支持'W', 这种情况需要特殊处理
    if 'W' in day_of_month:
        logger.warning(f"APScheduler不支持'W'工作日标记, 将替换为通配符: {day_of_month}")
        day_of_month = '*'
    
    # 5. 处理 '#' - 月中的第n个星期几, 例如 '6#3' 表示第3个星期六
    # APScheduler不支持'#'语法, 这种情况需要特殊处理
    if '#' in day_of_week:
        logger.warning(f"APScheduler不支持'#'特定序号标记, 将替换为通配符: {day_of_week}")
        day_of_week = '*'
    
    # 6. 处理星期值 - Quartz使用1-7表示星期一到星期日, APScheduler使用0-6表示星期一到星期日
    # 将1-7转换为0-6
    if day_of_week not in ['*', '?']:
        days = []
        for part in day_of_week.split(','):
            if '-' in part:
                start, end = map(int, part.split('-'))
                days.extend([str((i % 7)) for i in range(start, end + 1)])
            elif part.isdigit():
                days.append(str((int(part) % 7)))
            else:
                days.append(part)  # 保留其他格式, 如 'last', '*/2'等
        day_of_week = ','.join(days)
    
    # 7. 处理 '0/5' 这样的格式 - 每5分钟执行一次
    # APScheduler也支持这种格式, 但格式可能不同
    # 例如, '0/5' 在APScheduler中也可以表示为 '*/5'
    minute = minute.replace('0/', '*/')
    second = second.replace('0/', '*/')
    hour = hour.replace('0/', '*/')
    
    # 构建APScheduler兼容的cron表达式
    apscheduler_cron = f"{second} {minute} {hour} {day_of_month} {month} {day_of_week}"
    
    logger.debug(f"转换后的APScheduler cron表达式: {apscheduler_cron}")
    return apscheduler_cron

def parse_cron_expression(cron_expression: str):
    """
    解析cron表达式，支持Quartz和APScheduler格式
    
    Args:
        cron_expression: cron表达式
    
    Returns:
        一个包含cron表达式各部分的字典
    """
    # 首先尝试转换为APScheduler格式
    apscheduler_cron = convert_quartz_to_apscheduler(cron_expression)
    
    # 拆分转换后的表达式
    parts = apscheduler_cron.split()
    
    if len(parts) == 6:
        return {
            "second": parts[0],
            "minute": parts[1],
            "hour": parts[2],
            "day": parts[3],
            "month": parts[4],
            "day_of_week": parts[5]
        }
    elif len(parts) == 5:
        return {
            "minute": parts[0],
            "hour": parts[1],
            "day": parts[2],
            "month": parts[3],
            "day_of_week": parts[4]
        }
    else:
        raise ValueError(f"不支持的cron表达式格式: {cron_expression}")